What is simple-oauth2?
The simple-oauth2 npm package is a straightforward and flexible library for implementing OAuth2 authentication in Node.js applications. It provides a simple API to handle the OAuth2 authorization flows, including obtaining access tokens, refreshing tokens, and revoking tokens.
What are simple-oauth2's main functionalities?
Authorization Code Flow
This feature allows you to generate an authorization URL for the Authorization Code Flow. Users can visit this URL to authorize your application and obtain an authorization code.
const { AuthorizationCode } = require('simple-oauth2');
const client = new AuthorizationCode({
client: {
id: 'your-client-id',
secret: 'your-client-secret',
},
auth: {
tokenHost: 'https://authorization-server.com',
tokenPath: '/oauth/token',
authorizePath: '/oauth/authorize',
},
});
const authorizationUri = client.authorizeURL({
redirect_uri: 'http://localhost:3000/callback',
scope: 'user_profile',
state: 'random-string',
});
console.log('Visit this URL to authorize:', authorizationUri);
Obtaining Access Token
This feature allows you to exchange an authorization code for an access token. The access token can then be used to access protected resources on behalf of the user.
const tokenParams = {
code: 'authorization-code',
redirect_uri: 'http://localhost:3000/callback',
scope: 'user_profile',
};
client.getToken(tokenParams)
.then((result) => {
const accessToken = client.createToken(result);
console.log('Access Token:', accessToken.token);
})
.catch((error) => {
console.error('Access Token Error', error.message);
});
Refreshing Access Token
This feature allows you to refresh an expired access token using a refresh token. The new access token can then be used to continue accessing protected resources.
const token = client.createToken({
access_token: 'existing-access-token',
refresh_token: 'existing-refresh-token',
expires_in: '3600',
});
token.refresh()
.then((result) => {
const refreshedToken = client.createToken(result);
console.log('Refreshed Token:', refreshedToken.token);
})
.catch((error) => {
console.error('Refresh Token Error', error.message);
});
Revoking Access Token
This feature allows you to revoke an access token, making it invalid for further use. This is useful for logging out users or invalidating tokens for security reasons.
const token = client.createToken({
access_token: 'existing-access-token',
refresh_token: 'existing-refresh-token',
expires_in: '3600',
});
token.revoke('access_token')
.then(() => {
console.log('Access Token Revoked');
})
.catch((error) => {
console.error('Revoke Token Error', error.message);
});
Other packages similar to simple-oauth2
passport-oauth2
passport-oauth2 is a strategy for the Passport authentication middleware that implements OAuth 2.0. It is highly configurable and can be used with various OAuth 2.0 providers. Compared to simple-oauth2, passport-oauth2 is more integrated with the Passport ecosystem, making it a good choice if you are already using Passport for authentication.
client-oauth2
client-oauth2 is a lightweight and flexible library for OAuth 2.0 in JavaScript. It supports multiple OAuth 2.0 flows and is easy to use in both Node.js and browser environments. Compared to simple-oauth2, client-oauth2 offers a more minimalistic approach and can be a good choice for developers looking for a smaller library.
axios-oauth-client
axios-oauth-client is a library that integrates OAuth 2.0 with the popular Axios HTTP client. It simplifies the process of making authenticated HTTP requests using OAuth 2.0 tokens. Compared to simple-oauth2, axios-oauth-client is more focused on integrating OAuth 2.0 with Axios, making it a good choice if you are already using Axios for HTTP requests.
Simple OAuth2
Node.js client library for OAuth2. OAuth2 allows users to grant access to restricted resources by third party applications.
Table of Contents
Requirements
The node client library is tested against Node 8 LTS and newer versions. Older node versions are unsupported.
Usage
Install the client library using npm:
npm install --save simple-oauth2
Create a new instance by specifying the minimal configuration
const credentials = {
client: {
id: '<client-id>',
secret: '<client-secret>'
},
auth: {
tokenHost: 'https://api.oauth.com'
}
};
const oauth2 = require('simple-oauth2').create(credentials);
For more detailed configuration information see API Documentation
OAuth2 Supported grants
Depending on your use case, any of the following supported grant types may be useful:
Authorization Code
The Authorization Code grant type is made up from two parts. At first your application asks to the user the permission to access their data. If the user approves the OAuth2 server sends to the client an authorization code. In the second part, the client POST the authorization code along with its client secret to the oauth server in order to get the access token.
async function run() {
const oauth2 = require('simple-oauth2').create(credentials);
const authorizationUri = oauth2.authorizationCode.authorizeURL({
redirect_uri: 'http://localhost:3000/callback',
scope: '<scope>',
state: '<state>'
});
res.redirect(authorizationUri);
const tokenConfig = {
code: '<code>',
redirect_uri: 'http://localhost:3000/callback',
scope: '<scope>',
};
try {
const result = await oauth2.authorizationCode.getToken(tokenConfig);
const accessToken = oauth2.accessToken.create(result);
} catch (error) {
console.log('Access Token Error', error.message);
}
}
run();
Password Credentials Flow
The Password Owner grant type is suitable when the resource owner has a trust relationship with the client, such as its computer operating system or a highly privileged application. Use this flow only when other flows are not viable or when you need a fast way to test your application.
async function run() {
const oauth2 = require('simple-oauth2').create(credentials);
const tokenConfig = {
username: 'username',
password: 'password',
scope: '<scope>',
};
try {
const result = await oauth2.ownerPassword.getToken(tokenConfig);
const accessToken = oauth2.accessToken.create(result);
} catch (error) {
console.log('Access Token Error', error.message);
}
}
run();
Client Credentials Flow
The Client Credentials grant type is suitable when client is requesting access to the protected resources under its control.
async function run() {
const oauth2 = require('simple-oauth2').create(credentials);
const tokenConfig = {
scope: '<scope>',
};
try {
const result = await oauth2.clientCredentials.getToken(tokenConfig);
const accessToken = oauth2.accessToken.create(result);
} catch (error) {
console.log('Access Token error', error.message);
}
}
run();
Access Token object
When a token expires we need to refresh it. Simple OAuth2 offers the AccessToken class that add a couple of useful methods to refresh the access token when it is expired.
async function run() {
const tokenObject = {
'access_token': '<access-token>',
'refresh_token': '<refresh-token>',
'expires_in': '7200'
};
let accessToken = oauth2.accessToken.create(tokenObject);
if (accessToken.expired()) {
try {
const params = {
scope: '<scope>',
};
accessToken = await accessToken.refresh(params);
} catch (error) {
console.log('Error refreshing access token: ', error.message);
}
}
}
run();
The expired
helper is useful for knowing when a token has definitively expired. However, there is a common race condition when tokens are near expiring. If an OAuth 2.0 token is issued with a expires_in
property (as opposed to an expires_at
property), there can be discrepancies between the time the OAuth 2.0 server issues the access token and when it is received.
These come down to factors such as network and processing latency and can be worked around by preemptively refreshing the access token:
async function run() {
const EXPIRATION_WINDOW_IN_SECONDS = 300;
if (token.expired(EXPIRATION_WINDOW_IN_SECONDS)) {
try {
accessToken = await accessToken.refresh();
} catch (error) {
console.log('Error refreshing access token: ', error.message);
}
}
}
run();
When you've done with the token or you want to log out, you can revoke the access and refresh tokens.
async function run() {
try {
await accessToken.revoke('access_token');
await accessToken.revoke('refresh_token');
} catch (error) {
console.log('Error revoking token: ', error.message);
}
}
run();
As a convenience method, you can also revoke both tokens in a single call:
async function run() {
try {
await accessToken.revokeAll();
} catch (error) {
console.log('Error revoking token: ', error.message);
}
}
run();
Errors
Errors are returned when a 4xx or 5xx status code is received.
BoomError
As a standard boom error you can access any of the boom error properties. The total amount of information varies according to the generated status code.
async function run() {
try {
await oauth2.authorizationCode.getToken();
} catch(error) {
console.log(error);
}
}
run();
Debugging the module
This module uses the debug module to help on error diagnosis. Use the following environment variable to help in your debug journey:
DEBUG=*simple-oauth2*
API
For a complete reference, see the module API.
Usage examples
For complete reference examples, see the example folder.
Contributing
See CONTRIBUTING
Authors
Andrea Reginato
Contributors
Special thanks to the following people for submitting patches.
Changelog
See CHANGELOG
License
Simple OAuth 2.0 is licensed under the Apache License, Version 2.0
Thanks to Open Source
Simple OAuth 2.0 come to life thanks to the work I've made in Lelylan, an open source microservices architecture for the Internet of Things. If this project helped you in any way, think about giving us a star on Github.